# -*- coding: utf_8 -*-
# @Author : yh
# @Time : 2021/3/2 10:07
# @Remark: 参数相关处理
import logging
from typing import List
from urllib.parse import unquote

from mxsoftpy.exception import ParamsError


def check_params(params: object, params_list: object) -> object:
    """
    此方法用于校验参数是否完整
    :param params: 要校验的参数字典
    :param params_list: 要校验的参数名称
    """
    for param in params_list:
        if param not in params:
            raise ParamsError('获取必填参数%s失败' % param)
    return True


def get_pagination_params(params: dict = None):
    """
    获取分页参数
    :param params: 参数字典
    :return:
    """
    query = dict()
    if not params:
        return query

    try:
        if params.get('pagesize'):
            query['page_size'] = int(params['pagesize'])
        if params.get('pageindex'):
            query['page_index'] = int(params['pageindex'])
        if params.get('sortkey'):
            query['order_by'] = params['sortkey']
        query['is_desc'] = True if params.get('sortop') and int(params['sortop']) != 0 else False
    except ValueError as e:
        logging.error('错误的分页参数, 无法转为int类型, %s' % str(e))
        raise ParamsError('错误的分页参数, 无法转为int类型%')

    return query


def update_select_params(params: dict, paging: dict = None, check_list: list = None) -> dict:
    """
    更新查询参数，添加分页、去除空值
    :param params: 查询参数
    :param paging: 分页参数（字典中包含分页参数即可）
    :param check_list: 需要检查的字段列表，不传默认全部检查
    :return:
    """
    check_list = check_list or list()
    paging_query = get_pagination_params(paging)
    for k, v in params.items():
        if v == '' and k not in check_list:
            if params.get('default_expression'):  # 少了一个参数，default_expression随之更改（从末尾依次删除）
                params['default_expression'] = params['default_expression'].rsplit(' ', 2)[0]
        else:
            paging_query[k] = v

    return paging_query


def pagination(res_dict: dict, query: dict, total: int) -> dict:
    """
    给数据添加总页数、当前页、每页条数
    :param res_dict: 查询数据字典
    :param query: 查询参数
    :param total: 总条数
    :return: 返回到前端的数据
    """
    res_dict['pageindex'] = query.get('page_index') or 1
    if query.get('page_size'):
        res_dict['pagesize'] = query['page_size']
        res_dict['totalpages'] = total // query['page_size'] + 1 if total % query['page_size'] else total // query[
            'page_size']
    else:
        res_dict['pagesize'] = total
        res_dict['totalpages'] = 1

    return res_dict


def paging_data(data: iter, **paging) -> dict:
    """
    对列表数据进行分页处理，只返回给前端分页后的部分
    :param data: 总的数据（有些时候，数据分别存储在多个位置，每次都会全部查询出来，而前端又需要分页，此时，可使用此函数分页）
    :param paging: 分页参数
    """
    res_dict = dict()
    res_dict['pageindex'] = paging.get('page_index') or 1
    res_dict["total"] = len(data)
    if paging.get('page_size'):
        res_dict['data'] = data[(res_dict['pageindex'] - 1) * paging['page_size']:res_dict['pageindex'] * paging[
            'page_size']]
        res_dict['pagesize'] = paging['page_size']
        res_dict['totalpages'] = len(data) // paging['page_size'] + 1 if len(data) % paging[
            'page_size'] else len(data) // paging['page_size']
    else:
        res_dict['data'] = data
        res_dict['pagesize'] = len(data)
        res_dict['totalpages'] = 1

    return res_dict


def struct_dict(type_dispose=None, **kwargs):
    """
    参数处理
    l y w 2021-3-8
    :param type_dispose: 状态
    :param kwargs:
    :return: dict
    """
    if type_dispose is not None:
        if kwargs.get("page_index"):
            kwargs.pop("page_index")
        if kwargs.get("page_size"):
            kwargs.pop("page_size")
    res_data = {}
    for key, val in kwargs.items():
        if val is None or val == "":
            continue
        res_data[key] = val
    return res_data


def pro_decode(**params) -> dict:
    """
    对编码出现的加号空格问题进行处理
    :param params:  要处理的参数
    """
    for k, v in params.items():
        if isinstance(v, str):
            params[k] = unquote(v)

    return params


def pro_null_value(**kwargs) -> dict:
    """
    对参数的空值进行处理，方便model校验时给默认值
    :param kwargs:  要处理的参数
    """
    for key in list(kwargs.keys()):
        if not kwargs.get(key):
            del kwargs[key]

    return kwargs



def process(obj, key, default, option=None):
    """
    判断是否有此参数，没有返回默认值
    obj 为容器对象
    key 为查找对象
    default 为如果没有此值的返回对象
    option 规定查找对象的范围

    """
    key = obj[key] if obj.get(key) else default
    if option and key not in option:
        key = default
    return key
